<template>
  <div class="gnb-tree" onselectstart="return false">
    <div class="node"
         v-for="item in data"
    >
      <div class="flex-horiz node-line cursor-d"
           :class="selectedFolder && selectedFolder.key === item.key ? 'bg-primary color-white active' :''"
           :style="{'padding-left': `${20 * deepLevel + 10}px` }"
           @mouseup="(e)=>onMouseUp(e, item)"
      >
        <div class=" cursor-p pr-xs ptb-sm"
             v-if="item.children && item.children.length"
             @click="expands[item.key] = !expands[item.key]"
        >
          <i class="el-icon-caret-right" v-if="!expands[item.key]"></i>
          <i class="el-icon-caret-bottom" v-else></i>
        </div>
        <div class="flex-grow ptb-sm"
             v-if="item.birthTime && renameTarget !== item"
             @click="onClickFolder(item)"
             @mousedown.stop.right="e => onPressEnterRight(e,item)"
        >
          {{ item.name }}
        </div>
        <div class="flex-grow ptb-xs pr-xs"
             v-else-if="renameTarget === item"
        >
          <el-input v-model="item.rename"
                    v-gnb-autofocus
                    @keydown.enter="onPassEnterRename(item)"
                    @blur="renameTarget = null"
          ></el-input>
        </div>
        <div class="flex-grow ptb-xs pr-xs"
             v-else
        >
          <el-input v-model="item.name"
                    v-gnb-autofocus
                    @keydown.enter="onPassEnter(item)"
                    @blur="onInputBlur(item)"
          ></el-input>
        </div>
      </div>
      <gnb-tree
          v-if="expands[item.key] && item.children && item.children.length"
          :data="item.children"
          :deep-level="deepLevel+1"
      ></gnb-tree>
    </div>
  </div>
</template>

<script lang="ts">
import {ref, watch, toRefs, computed, toRaw, reactive, onBeforeUnmount, getCurrentInstance} from "vue";
import {mapState, useStore} from "vuex";
import {IpcRenderer} from "@/utils/render/common";
import {ElDialog, ElMessage} from "element-plus";
import {findInTree} from "@/utils/array.utils";
import {CommonListener} from "@/utils/listener.utils";
import {DirTree} from "@/utils/main/file.uitls";

export default {
  name: 'gnb-tree',
  mixins: [],
  components: {},
  props: {
    data: {
      default: () => ([]),
    },
    deepLevel: {
      default: 0,
    }
  },
  data() {
    return {}
  },
  setup(props) {

    const instance = getCurrentInstance();
    const store = useStore();
    const {data} = toRefs(props);
    const expands = ref({})
    const showChildren = ref(false);

    const onMouseUp = (e, item) => {
      store.dispatch("setTarget", item);
    }

    const onClickFolder = (item) => {
      store.dispatch("setSelectedFolder", item);
    }

    const onPassEnter = async (item) => {
      const res = await IpcRenderer.invoke("addItem", {
        path: item.path,
        name: item.name,
        isFile: item.isFile,
      });
      if (res) {
        return await store.dispatch("syncNoteDirectories");
      }
      ElMessage.error("添加文件夹失败！");
    }

    const onInputBlur = async (item) => {
      await store.dispatch("syncNoteDirectories");
    }

    const selectedFolder = computed(() => {
      return store.state.note.selectedFolder;
    })

    watch(
        () => data.value,
        (v) => {
          v.forEach(item => {
            if (
                item.children.find(x => x.birthTime === null)
                || findInTree(item.children, (item) => item === selectedFolder)
            ) {
              expands.value[item.key] = true;
            }
          })
        },
        {deep: true,}
    )

    const renameTarget = ref(null);
    const menuTarget = ref(null);

    const onClickMenuRename = (item) => {
      if (item !== menuTarget.value) return;
      menuTarget.value.rename = menuTarget.value.name;
      renameTarget.value = menuTarget.value;
    }

    const onClickMenuDelete = (item) => {
      if (item !== menuTarget.value) return;
      instance.proxy['$confirm'](`确定删除文件夹 < ${menuTarget.value.name} > ？`, '删除文件夹')
          .then(async () => {
            await IpcRenderer.invoke("deleteItem", toRaw(menuTarget.value));
            await store.dispatch("syncNoteDirectories");
          });
    }

    const onPassEnterRename = (item) => {
      const res = IpcRenderer.invoke("renameItem", toRaw(item));
      store.dispatch("syncNoteDirectories");
    }

    const onPressEnterRight = (e, item) => {
      e.stopPropagation();
      menuTarget.value = item;
      CommonListener.trigger("showRightMenu", e, "tree", item);
    }

    const onClickAddFolder = (item) => {
      if (item !== menuTarget.value) return;
      item.children.push(new DirTree("",item.path, [], false));
      expands.value[item.key] = true;
    }

    const removeRename = CommonListener.addListener("onClickTreeMenuRename", onClickMenuRename);
    const removeDelete = CommonListener.addListener("onClickTreeMenuDelete", onClickMenuDelete);
    const removeAddFolder = CommonListener.addListener("onClickTreeMenuAddFolder", onClickAddFolder);


    onBeforeUnmount(() => {
      removeRename();
      removeDelete();
      removeAddFolder();
    })


    return {
      showChildren,
      selectedFolder,
      expands,
      renameTarget,

      onMouseUp,
      onClickFolder,
      onPassEnter,
      onInputBlur,
      onPassEnterRename,
      onPressEnterRight,
    }
  },
  computed: {},
  watch: {},
  created() {
  },
  mounted() {
  },
  beforeUnmount() {
  },
  activated() {
  },
  deactivated() {
  },
  methods: {}
};
</script>

<style scoped lang="less">

.gnb-tree {

}

.node-line {
  font-size: 14px;

  &:hover:not(.active) {
    background-color: #a7cafa;
  }
}
</style>